package ar.edu.uba.fi.jmit.monitorengine.core;

import ar.edu.uba.fi.jmit.integrationcommons.Event;
import ar.edu.uba.fi.jmit.integrationcommons.EventPriority;
import ar.edu.uba.fi.jmit.monitorengine.Constants;
import ar.edu.uba.fi.jmit.monitorengine.MonitorEngineTestCase;
import ar.edu.uba.fi.jmit.monitorengine.ResourceProperties;
import ar.edu.uba.fi.jmit.monitorengine.core.monitormanager.MonitorNameTypeManager;
import ar.edu.uba.fi.jmit.monitorengine.exception.MonitorEngineException;
import ar.edu.uba.fi.jmit.monitorengine.mock.MockMonitor1;
import ar.edu.uba.fi.jmit.monitorengine.mock.MockMonitor2;

public class MonitorNameTypeManagerTestCase extends MonitorEngineTestCase {

	public void testGetMonitor() {
		MonitorNameTypeManager manager = new MonitorNameTypeManager();
		MockMonitor1.restart();
		MockMonitor2.restart();
		try {
			Event event = createEvent("name1");
			MockMonitor1 monitor = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertNotNull(monitor);
			monitor.doExecute(event);
			assertEquals(1, MockMonitor1.getExecutedEvents().size());
			MockMonitor1 monitor2 = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertEquals(monitor, monitor2);
			
			event = createEvent("name2");
			MockMonitor1 monitor3 = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertNotSame(monitor, monitor3);
			event.setSource("");
			event.setPriority(EventPriority.ALERT);
			MockMonitor1 monitor4 = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertNotSame(monitor, monitor4);
			assertEquals(monitor3, monitor4);//the name didn't change
			
			event = createEvent("name3");
			MockMonitor2 monitor5 = (MockMonitor2) manager.getMonitor(MockMonitor2.class.getName(), event);
			assertNotSame(monitor5, monitor);
			assertNotSame(monitor5, monitor2);
			assertNotSame(monitor5, monitor3);
			assertNotSame(monitor5, monitor4);
			try {
				manager.getMonitor(MockMonitor1.class.getName(), event);
				fail("Exception should bw thrown!");
			}catch(MonitorEngineException e) {
				//expected
			}
			
		} catch (Exception e) {
			fail(e);
		}
	}
	
	public void testRemove() {
		MonitorNameTypeManager manager = new MonitorNameTypeManager();
		MockMonitor1.restart();
		MockMonitor2.restart();
		try {
			Event event = createEvent("name1");
			MockMonitor1 monitor = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertNotNull(monitor);
			monitor.doExecute(event);
			assertEquals(1, MockMonitor1.getExecutedEvents().size());
			MockMonitor1 monitor2 = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertEquals(monitor, monitor2);
			manager.removeMonitor("name1");
			monitor2 = (MockMonitor1) manager.getMonitor(MockMonitor1.class.getName(), event);
			assertNotSame(monitor, monitor2);
			
			try {
				manager.getMonitor(MockMonitor2.class.getName(), event);
				fail("Exception should be thrown!");
			}catch(MonitorEngineException e) {
				//expected
			}
			manager.removeMonitor("name1");
			manager.getMonitor(MockMonitor2.class.getName(), event);
			
		} catch (Exception e) {
			fail(e);
		}
	}
	
	private Event createEvent(String monitorName) {
		Event event = new Event();
		event.setSource("SingletonTypeManagerTestCase");
		event.setPriority(EventPriority.NORMAL);
		event.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), monitorName);
		return event;
	}
}
